/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gordonwong.materialsheetfab.sample.models;

import com.gordonwong.materialsheetfab.sample.ResourceTable;
import com.gordonwong.materialsheetfab.sample.utils.DateFormatUtils;
import ohos.app.Context;

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;

/**
 * Created by Gordon Wong on 7/18/2015.
 * <p>
 * Note model.
 */
public class Note {

    private static final String[] ACTIONS_PEOPLE = {"call", "email", "meet up with",
            "hang out with"};
    private static final String[] ACTIONS_OBJECTS = {"clean", "buy", "sell", "fix"};
    private static final String[] NAMES = {"Sherry", "Gordon", "Tom", "Kevin", "Brian", "Naomi",
            "Ali", "Jennifer"};
    private static final String[] OBJECTS = {"desk", "car", "motorcycle", "computer", "laptop"};
    private static final String WORDS = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.";
    private static final String[] CITIES = {"San Francisco", "Campbell", "Lincoln", "New York",
            "Silverton", "Scarface", "King Salmon"};

    private static final String[] LIST_TITLES = {"shopping", "to bring", "on sale", "look for",
            "buy", "get rid of"};
    private static final String[] LIST_DELIMITERS = {"•", "-"};
    private static final String[] LIST_GROCERIES = {"almond milk", "coconut water", "cucumber",
            "green apples"};
    private static final String[] LIST_CAMPING = {"lantern", "smores", "extra blankets",
            "warm socks", "first aid kit", "tent"};

    private static final int NUM_WORDS = 4;
    private static final int DATE_RANGE = 60;

    private String title;
    private String note;
    private String info;
    private int infoImage;
    private String color;

    private Note(String title, String note, String info, int infoImage, String color) {
        this.title = title;
        this.note = note;
        this.info = info;
        this.infoImage = infoImage;
        this.color = color;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public int getInfoImage() {
        return infoImage;
    }

    public void setInfoImage(int infoImage) {
        this.infoImage = infoImage;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public static Note randomNote(Context context) {
        double rand = Math.random();
        String title = "";
        String note = "";
        NoteInfo info = new NoteInfo("", 0);
        String color = getRandomColor(context);

        // Title only
        if (rand >= 0.65) {
            title = getRandomActivity();
            if (Math.random() >= 0.7) {
                info = getRandomDate();
            }
        }
        // Title and note
        else if (rand >= 0.3) {
            title = getRandomActivity();
            note = getRandomWords();
            if (Math.random() >= 0.7) {
                info = getRandomInfo();
            }
        }
        // Lists
        else {
            title = getRandomListTitle();
            note = getRandomList();
            if (Math.random() >= 0.7) {
                info = getRandomLocation();
            }
        }

        return new Note(capitalize(title), note, info.info, info.infoImage, color);
    }

    private static String getRandomActivity() {
        if (Math.random() >= 0.5) {
            return getRandomString(false, ACTIONS_PEOPLE) + " " + getRandomString(false, NAMES);
        } else {
            return getRandomString(false, ACTIONS_OBJECTS) + " " + getRandomString(false, OBJECTS);
        }
    }

    private static String getRandomWords() {
        SecureRandom secureRandom = new SecureRandom();
        int rand = (int) (secureRandom.nextFloat() * NUM_WORDS) + 1;
        StringBuilder words = new StringBuilder();
        for (int i = 0; i < rand; i++) {
            words.append(WORDS);
            if (i != rand - 1) {
                words.append(" ");
            }
        }
        return words.toString();
    }

    private static String getRandomListTitle() {
        String title = getRandomString(true, LIST_TITLES);
        if (!isEmpty(title)) {
            title += ":";
        }
        return title;
    }

    private static String getRandomList() {
        String[] list = (String[]) getRandomItem(new Object[]{LIST_GROCERIES, LIST_CAMPING});
        String delimiter = getRandomString(true, LIST_DELIMITERS);
        if (!isEmpty(delimiter)) {
            delimiter += " ";
        }
        StringBuilder listStr = new StringBuilder();
        for (int i = 0; i < list.length; i++) {
            listStr.append(delimiter).append(list[i]);
            if (i != list.length - 1) {
                listStr.append("\n");
            }
        }
        return listStr.toString();
    }

    private static NoteInfo getRandomInfo() {
        NoteInfo[] infos = new NoteInfo[]{getRandomDate(), getRandomLocation()};
        return (NoteInfo) getRandomItem(infos);
    }

    private static NoteInfo getRandomDate() {
        Calendar cal = Calendar.getInstance();
        SecureRandom secureRandom = new SecureRandom();
        cal.add(Calendar.DATE, (int) (secureRandom.nextFloat() * DATE_RANGE));
        String date = DateFormatUtils.dateFormat();
        return new NoteInfo(date, ResourceTable.Media_ic_event_white_24dp);
    }

    private static NoteInfo getRandomLocation() {
        String location = getRandomString(false, CITIES);
        return new NoteInfo(location, ResourceTable.Media_ic_place_white_24dp);
    }

    private static String getRandomColor(Context context) {
        String[] colors;
        if (Math.random() >= 0.6) {
            colors = context.getStringArray(ResourceTable.Strarray_note_accent_colors);
        } else {
            colors = context.getStringArray(ResourceTable.Strarray_note_neutral_colors);
        }
        return colors[((int) (Math.random() * colors.length))];
    }

    private static String capitalize(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    }

    private static String getRandomString(boolean includeEmpty, String[] strings) {
        if (includeEmpty) {
            ArrayList<String> stringsWithEmpty = new ArrayList<>(Arrays.asList(strings));
            stringsWithEmpty.add("");
            return (String) getRandomItem(stringsWithEmpty.toArray());
        }
        return (String) getRandomItem(strings);
    }

    private static Object getRandomItem(Object[] objs) {
        return objs[((int) (Math.random() * objs.length))];
    }

    private static class NoteInfo {

        private String info;
        private int infoImage;

        private NoteInfo(String info, int infoImage) {
            this.info = info;
            this.infoImage = infoImage;
        }

    }

    private static boolean isEmpty(String content) {
        return content.isEmpty();
    }
}
